#include "stdio.h"
#include "stdlib.h"
typedef unsigned char *byte_pointer;
typedef unsigned int uint;

int x_combine_y(int x, int y)
{
    printf("x == %x\r\ny == %x\r\n",x,y);

    return (x & 0xff) | (y & 0xffffff00);
}
unsigned replace_byte(unsigned source, unsigned char replacement, int position)
{
    if((0 <= position) && (3 >= position))
    {
        source = source &~(0xff << (8 * position)) | (replacement << (8 * position));
    }
    return source;


}
int One_or_zero(int x)
{
    return !(x ^ -1) || !(x ^ 0) || !((x & 0xff000000) ^ 0xff000000) || !((x & 0xff) ^ 0);
}

int int_shifts_are_logical(void)
{
    return ((-1 >> 1) & 0x80000000) == 0x80000000;
}

int sra(int x, int k)
{
    int xsrl = (unsigned) x >> k;
    int w = 8*sizeof(int);   //32
    /*printf("w == %d\r\n",w);*/
    int MSBit = (x & (1 << (w - 1)));    //x & 0x80000000
    int OneOr0 = !((unsigned)MSBit ^ (1 << (w - 1)));
    /*printf("MSBit == %x\r\n OneOr0 == %x\r\n",MSBit,OneOr0);*/
    //if x < 0, bit[31:(32-k)] == 0b1111.....
    //if k == 1, bit[31] = -1 - (0x1 << (w - k -1) - 1)
    //  0xffffffff - 0x7fffffff
    /*printf("(0 - oneor0) == %x\r\n((oneor0 << (w - k )) - oneor0) == %x\r\n(oneor0 << (w - k ) == %x\r\n",(0 - oneor0),((oneor0 << (w - k )) - oneor0),(oneor0 << (w - k )));*/
    int Modified_value = ( 0 - OneOr0 - ((OneOr0 << (w - k )) - OneOr0));
    /*printf("xsrl == %x  Modified_value == %x\r\n",xsrl,Modified_value);*/
    xsrl |= Modified_value;
    return xsrl;
}

unsigned srl(unsigned x, int k)
{
    unsigned xsra = (int) x >> k;
    int w = 8*sizeof(int);
    /*printf("w == %d\r\n",w);*/
    int MSBit = (x & (1 << (w - 1)));    //x & 0x80000000

    int OneOr0 = !((unsigned)MSBit ^ (1 << (w - 1)));
    /*printf("MSBit == %x\r\n OneOr0 == %x\r\n",MSBit,OneOr0);*/
    //if MSBit == 0x80000000, there'll be a problem
    //  0xffffffff - 0x7fffffff
    /*printf("(0 - OneOr0) == %x\r\n((OneOr0 << (w - k )) - OneOr0) == %x\r\n(OneOr0 << (w - k ) == %x\r\n",(0 - OneOr0),((OneOr0 << (w - k )) - OneOr0),(OneOr0 << (w - k )));*/

    int Modified_value = ( 0 - OneOr0 - ((OneOr0 << (w - k )) - OneOr0));
    /*printf("xsra == %x  Modified_value == %x\r\n",xsra,Modified_value);*/
    xsra &= ~Modified_value;
    return xsra;

}

int even_ones(unsigned x)
{
    /*Return 1 when x contains an even number of 1s; 0 otherwise.*/
    x = x ^ (x >> 1);
    x = x ^ (x >> 2);
    x = x ^ (x >> 4);
    x = x ^ (x >> 8);
    x = x ^ (x >> 16);
    return x & 0x1;
}

int leftmost_one(unsigned x)
{
    /*Generate mask indicating leftmost 1 in x. Assume w = 32.*/
    /*For example 0xFF00 -> 0x8000, and 0x6600 -> 0x4000.*/
    /*If x = 0, then return 0.*/
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return ((x + 1) >> 1);
}
int lower_bits( int n)
{
    /*Make with least signficant n bits set to 1*/
    /*Examples: n = 6 --> 0x3f, n = 17 --> 0x1FFFF*/
    /*Assume 1 <= n <= 2*/

    return (((1 << (n - 1)) - 1) << 1) | 1;

}
unsigned rotate_right(unsigned x, int n)
{
    /*Do rotating right shift. Assume 0 <= n < w*/
    /*Examples when x = 0x12345678 and w = 32:*/
    /*n = 4 -> 0x81234567, n = 20 -> 0x45678123*/

    // 1, set all bits of x
    unsigned x_original = x, w = 0, mask = 0, shift_value = 0;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    //x = (x + 1) >> 1;        // Now all bits of x are 1
    //x = (((x + 3) >> 2) << 2);
    printf("0.    x == 0x%x\r\n",x);


    // 2, calculate how many bits x has
    //    (1 on bit[n]) + (1 on bit[n + 1])
    x = (x & 0x55555555) + ((x & 0xaaaaaaaa) >> 1); // 1s in every 2 bits
    printf("1.    x == 0x%x\r\n",x);
    x = (x & 0x33333333) + ((x & 0xcccccccc) >> 2); // 1s in every 4 bits
    printf("2.    x == 0x%x\r\n",x);
    x = (x & 0x0f0f0f0f) + ((x & 0xf0f0f0f0) >> 4); // 1s in every 8 bits
    printf("3.    x == 0x%x\r\n",x);
    x = (x & 0x00ff00ff) + ((x & 0xff00ff00) >> 8); // 1s in every 16 bits
    printf("4.    x == 0x%x\r\n",x);
    x = (x & 0x0000ffff) + ((x & 0xffff0000) >> 16);// 1s in 32 bits
    x = (((x + 3) >> 2) << 2);
    printf("5.    x == 0x%x\r\n",x);

    // 3, shift and change the value of bit[w-1:w-1-n]
    w = x;
    mask = ((1 << x ) - 1 );


    shift_value = ((((1 << (n - 1)) - 1) << 1) | 1);
    printf("6.    shift_value == 0x%x\r\n",shift_value);

    shift_value =  (shift_value & x_original);        //now shift_value == x_original[n-1:0]
    printf("7.    shift_value == 0x%x\r\n",shift_value);

    x_original = (x_original >> n);
    printf("8.    x_original >> %x == 0x%x\r\n",n,x_original);

    shift_value = (shift_value << (w - n));
    printf("9.    shift_value == 0x%x\r\n",shift_value);

    x = shift_value | x_original;

    printf("10.    mask == 0x%x\r\n",mask);
    return x & mask;
}


int fits_bits(int x, int n)
{
/*    Return 1 when x can be represented as an n-bit, 2's complment*/
    /*number; 0 otherwise */
    /*Assume 1 <= n <= w*/
    int n_bits_1 = 0;

    //1, set all bits of x
    x = x | (x >> 1);
    x = x | (x >> 2);
    x = x | (x >> 4);
    x = x | (x >> 8);
    x = x | (x >> 16);
    printf("1.    x == 0x%x\r\n",x);

    //2, creat a number which has n bits 1
    n_bits_1 = ((1 << n ) - 1);
    printf("2.    n_bits_1 == 0x%x\r\n",n_bits_1);

    //3, if n_bits_1 has one more bit than x, than it can happen; otherwise there'll be an overflow
    return x == (n_bits_1 >> 1);


}
void main(int argc, char *argv[])
{
    if(argc == 3)
    {
        printf("fits_bits(%x) == %x \r\n",atoi(argv[1]),fits_bits(atoi(argv[1]),atoi(argv[2])));
    }
    else
        printf("Need 3 argument!\r\n");
}
